import os
from typing import Union

import yaml
from ..models.mdl_dev_env_app_cfgs import (
    CodeServerAppCfg,
    JupyterLabAppCfg,
    GenericWebAppCfg,
)
from ..configs import BUILTIN_APPS_CONFIG_FILE, EXTERNAL_APPS_CONFIG_FILE

code_server_app = CodeServerAppCfg()
jupyter_lab_app = JupyterLabAppCfg()
APP_TYPES = Union[CodeServerAppCfg, JupyterLabAppCfg, GenericWebAppCfg]
app_types: list[APP_TYPES] = [
    code_server_app,
    jupyter_lab_app,
]

generic_app_configs: dict[str, GenericWebAppCfg] = {}


def load_app_configs_from_file(config_yaml_file: str):
    with open(config_yaml_file, "r") as file:
        data = yaml.safe_load(file)
        for app_config in data:
            app_name = app_config["name"]
            generic_app_configs[app_name] = GenericWebAppCfg(
                app_name,
                app_config["description"],
                app_config.get("web_port", None),
                other_ports=app_config.get("other_ports", []),
                environments=app_config.get("environments", {}),
                volumes=app_config.get("volumes", []),
            )


load_app_configs_from_file(BUILTIN_APPS_CONFIG_FILE)
if os.path.exists(EXTERNAL_APPS_CONFIG_FILE):
    load_app_configs_from_file(EXTERNAL_APPS_CONFIG_FILE)


def get_app_cfg(app_name: str, img_tag: str) -> APP_TYPES:
    if app_name == "Generic App":
        image_name = img_tag.rsplit(":", 1)[0].rsplit("/")[
            -1
        ]  # for example, the result of `someurl/app/image:tag` will be 'image'
        return generic_app_configs[image_name]
    else:
        for app in app_types:
            if app.name == app_name:
                return app

    raise Exception(f"App {app_name} not found")
